package com.cpz.rabbitmq.controller;

import com.cpz.rabbitmq.message.DirectMessage;
import com.cpz.rabbitmq.message.FanoutMessage;
import com.cpz.rabbitmq.message.TopicMessage;
import com.cpz.rabbitmq.service.RabbitService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 消息控制器
 *
 * @author cpz
 * @since 2022/09/19
 */
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class MessageController {

    private final RabbitService rabbitService;

    /**
     * 路由模式：
     *      生产者将携带路由键的消息发送给直连交换机，交换机根据路由键值转发到队列名为该值的队列
     * @return
     */
    @GetMapping("/message/direct")
    public String direct() {
        rabbitService.send(new DirectMessage().setData("hello world"));
        return "直连交换机";
    }

    /**
     * 订阅模式（广播）：
     *      生产者将消息发送给扇型交换机，交换机将消息分发给所有绑定的队列，
     *      从这个过程可以看出，该交换机没有路由键(routingKey)概念
     *      但注意同一队列多个消费者只有其中一个消费了消息。
     * @return
     */
    @GetMapping("/message/fanout")
    public String fanout() {
        rabbitService.send(new FanoutMessage().setData("hello world"));
        return "扇型交换机";
    }

    /**
     * 主题模式：
     *      与直连交换机类似，但它的 路由建(routing key) 和 绑定值（key） 是有规则的
     *      规则： *：必须存在一个单词；#：存在零个或者多个单词
     *      例子：queue_topic.test  ->  queue_topic.#
     *      topic 实现了，direct 与 fanout 交换机功能
     * @return
     */
    @GetMapping("/message/topic")
    public String topic() {
        rabbitService.send(new TopicMessage().setData("hello world"));
        return "主题交换机";
    }
}
